﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web;
using Microsoft.ApplicationServer.Http.Dispatcher;
using System.Text;
using System.Security.Principal;
using Microsoft.ApplicationServer.Http.Description;
using ApiPrototype.Models;

namespace ApiPrototype.Handlers
{
    public class AuthorizationOperationHandler : HttpOperationHandler
    {
        public AuthorizationOperationHandler(AuthorizationAttribute attr) : base() { }

        protected override IEnumerable<HttpParameter> OnGetInputParameters()
        {
            yield return new HttpParameter("ctx", typeof(iphlEntities));
            yield return new HttpParameter("request", typeof(HttpRequestMessage));
        }

        protected override IEnumerable<HttpParameter> OnGetOutputParameters()
        {
            yield return new HttpParameter("studentId", typeof(int));
        }

        protected override object[] OnHandle(object[] req)
        {
            var ctx = req[0] as iphlEntities;
            var input = req[1] as HttpRequestMessage;

            var authHeader = input.Headers.Authorization;

            string username, password;

            if (input.Headers.Authorization == null || input.Headers.Authorization.Scheme != "Basic")
            {
                // If properly configured, this should never happen:
                // this OperationHandler should only be used when 
                // Basic authorization is required
                throw new ApiException("Method requires authorization.", HttpStatusCode.Unauthorized);
            }
            try
            {
                var encoded = input.Headers.Authorization.Parameter;
                var encoding = Encoding.GetEncoding("iso-8859-1");
                var userPass = encoding.GetString(Convert.FromBase64String(encoded));
                int sep = userPass.IndexOf(':');
                if (sep <= 0)
                {
                    throw new Exception();
                }

                username = userPass.Substring(0, sep);
                password = userPass.Substring(sep + 1, userPass.Length - sep - 1);
            }
            catch
            {
                // If properly configured, this should never happen:
                // indicates client is not sending a valid Authorization
                // header
                throw new ApiException("Invalid Authorization header.", HttpStatusCode.Unauthorized);
            }

            int stu_id;
            try
            {
                stu_id = Convert.ToInt32(username);
            }
            catch
            {
                throw new ApiException("Username invalid.", HttpStatusCode.Unauthorized);
            }

            bool valid = (ctx.STUDENT.Where(s => s.STU_ID == stu_id && s.STU_WACHTWOORD.Equals(password)).Count() == 1);

            if (!valid)
            {
                throw new ApiException("Combination username and password invalid.", HttpStatusCode.Unauthorized);
            }

            return new object[1] {stu_id};
        }
    }
}